package com.sprouting.personal.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.interfaces.common.ConstantPath;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Dict;
import com.sprouting.personal.model.entity.PsNotepad;
import com.sprouting.personal.model.entity.UploadFile;
import com.sprouting.personal.model.vo.PsNotepadVo;
import com.sprouting.personal.service.DictService;
import com.sprouting.personal.service.PsNotepadService;
import com.sprouting.personal.service.UploadFileService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * (PsNotepad)表控制层
 *
 * @author longx
 * @since 2022-12-18 23:09:17
 */
@Slf4j
@RestController
@RequestMapping("notepad")
public class PsNotepadController {

    @Autowired
    private PsNotepadService psNotepadService;
    @Autowired
    private UploadFileService uploadFileService;
    @Autowired
    private DictService dictService;

    /**
     * 文件存储基础路径
     */
    @Value("${upload.data.base.path}")
    private String basePath;


    /**
     * 第二步，上传图片到目录，但依旧属于临时文件
     * @param flagId iD，从 {@link UploadFileController#getFlag()} 中获取的
     * @param file 上传的文件
     * @return 文件保存位置
     */
    @PostMapping("/uploadContentImage")
    public ResultJson uploadContentImage(String flagId, @RequestParam(value = "file", required = false) MultipartFile file){
        if (CheckTool.checkNull(flagId)){
            return ResultJson.errorIllegal();
        }
        if (CheckTool.checkNull(basePath)){
            return ResultJson.error("图片存储路径未初始化，请补充application.properties配置信息");
        }
        String originalFilename = file.getOriginalFilename();
        if (CheckTool.checkNull(originalFilename)){
            return ResultJson.error("获取文件名失败");
        }
        String suffix = FileUtil.getSuffix(originalFilename).toLowerCase();
        if (CheckTool.checkNull(suffix)){
            // 检查特殊情况下的文件名不符合
            return ResultJson.error("非法上传图片名，不支持的后缀");
        }

        String path = String.format(ConstantPath.Path.NOTEPAD_ICO, basePath, StpUtil.getLoginIdAsString(), flagId, IdTool.getId(), suffix);
        File toFile = new File(path);
        // 上传路径
        if (!FileUtil.exist(toFile)){
            FileUtil.touch(toFile);
        }

        try {
            file.transferTo(toFile);
        } catch (IOException e) {
            log.error("图片上传失败", e);
            return ResultJson.error("图片上传失败");
        }

        // 只保存相对路径
        String replacePath = path.replace(basePath, "");

        UploadFile uploadFile = new UploadFile();
        uploadFile.setId(IdTool.getId());
        uploadFile.setUserId(StpUtil.getLoginIdAsString());
        uploadFile.setBindingId(flagId);
        uploadFile.setFileType(Constant.FileType.IMG);
        uploadFile.setSavePath(replacePath);
        uploadFile.setDelResource(Constant.YesOrNo.NO);
        uploadFile.setTempFile(Constant.TempFile.TEMP);
        uploadFile.setType(Constant.FileSourceType.NOTEPAD);
        EntityTool.buildSaveBase(uploadFile, StpUtil.getLoginIdAsString());
        uploadFileService.save(uploadFile);
        return ResultJson.success(replacePath);
    }

    /**
     * 修改记事本为已完成-或叫已废弃
     * @param id 记事本主键
     * @return
     */
    @PostMapping("/updateComplete")
    public ResultJson updateComplete(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }
        PsNotepad psNotepad = psNotepadService.getPsNotepadById(id);
        // 废弃
        psNotepad.setDiscard(Constant.YesOrNo.YES);
        EntityTool.buildUpdBase(psNotepad, StpUtil.getLoginIdAsString());
        psNotepadService.updateById(psNotepad);
        return ResultJson.success(psNotepad);
    }

    /**
     * 获取记事类型
     * @return
     */
    @GetMapping("/getNotepadType")
    public ResultJson getNotepadType(){
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.NOTEPAD_GROUP, StpUtil.getLoginIdAsString());
        return ResultJson.success(dictList);
    }

    /**
     * 根据条件分页查询记事本
     * @param page 分页参数
     * @param psNotepad 查询参数
     * @return
     */
    @PostMapping("/getNotepadListPage")
    public ResultJson getNotepadListPage(Page page, PsNotepad psNotepad){
        if (psNotepad == null){
            psNotepad = new PsNotepad();
        }
        if (psNotepad.getDiscard() == null){
            return ResultJson.error("必须指定查询的类型");
        }
        psNotepad.setUserId(StpUtil.getLoginIdAsString());
        Page<PsNotepadVo> notepadListPage = psNotepadService.getNotepadListPage(page, psNotepad);
        return ResultJson.success(notepadListPage);
    }

    /**
     * 保存记事本
     * @param psNotepad 记事本数据
     * @param flagId 记事本ID,也是图片的标记
     * @return
     */
    @ApiIdempotent
    @PostMapping("/saveNotepad")
    public ResultJson saveNotepad(@Validated(AddGroup.class) PsNotepad psNotepad, String flagId){
        if (CheckTool.checkNull(flagId)){
            return ResultJson.errorIllegal();
        }
        if (psNotepad.getDiscard() == null){
            psNotepad.setDiscard(Constant.YesOrNo.NO);
        }
        if (psNotepad.getImportance() == null){
            psNotepad.setImportance(Constant.ImportanceLevel.NO_IMPORTANT_NO_EMERGENCY);
        }
        if (CheckTool.checkNull(psNotepad.getFlagColour())){
            // 根据不同等级设置颜色
            // 2022年12月20日10:33:52 不设置，否则前面无法判断是否自定义颜色
            // String colour = getColour(psNotepad.getImportance());
            // psNotepad.setFlagColour(colour);
        }

        // 脏数据处理，还要对记录在文件表中的数据进行转生产，防止被干掉
        List<UploadFile> uploadFileList = uploadFileService.getUploadFileByBindingId(flagId);

        psNotepad.setId(IdTool.getId());
        psNotepad.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(psNotepad, StpUtil.getLoginIdAsString());
        psNotepadService.saveNotepad(psNotepad, uploadFileList);
        return ResultJson.success(psNotepad);
    }

    /**
     * 更新记事本
     * @param psNotepad 记事本数据
     * @return
     */
    @ApiIdempotent
    @PostMapping("/updNotepad")
    public ResultJson updNotepad(@Validated(UpdGroup.class) PsNotepad psNotepad) {
        List<UploadFile> uploadFileList = uploadFileService.getUploadFileByBindingId(psNotepad.getId());

        EntityTool.buildUpdBase(psNotepad, StpUtil.getLoginIdAsString());
        psNotepadService.updateNotepad(psNotepad, uploadFileList);
        return ResultJson.success(psNotepad);
    }

    /**
     * 根据主键删除记事本
     * @param id 记事本主键
     * @return
     */
    @ApiIdempotent
    @PostMapping("/delNotepadById")
    public ResultJson delNotepadById(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }

        List<UploadFile> uploadFileList = uploadFileService.getUploadFileByBindingId(id);
        psNotepadService.removeNotepad(id, uploadFileList, basePath);
        return ResultJson.success(null);
    }

    /**
     * 根据重要程度获取颜色
     * @param importance 重要性
     * @return 颜色
     */
    private String getColour(Integer importance){
        if (importance == null){
            // 绿色 #57B40D
            return "#85E931";
        } else if (Constant.ImportanceLevel.CORE.equals(importance)){
            // - #CD1D8A
            return "#E240AD";
        } else if (Constant.ImportanceLevel.IMPORTANT_EMERGENCY.equals(importance)){
            // #FE8787
            return "#FDADAE";
        } else if (Constant.ImportanceLevel.NO_IMPORTANT_EMERGENCY.equals(importance)){
            // #FD8F1E
            return "#FEAA54";
        } else if (Constant.ImportanceLevel.IMPORTANT_NO_EMERGENCY.equals(importance)){
            // #FCE407
            return "#FEEF63";
        } else {
            return "#81D70A";
        }
    }

}

